package com.xdjd.mobile.system.interceptor;

import cn.jiguang.common.utils.StringUtils;
import com.alibaba.fastjson.JSON;
import com.gitee.easyopen.ApiContext;
import com.gitee.easyopen.ApiMeta;
import com.gitee.easyopen.ApiResult;
import com.gitee.easyopen.interceptor.ApiInterceptorAdapter;
import com.xdjd.mobile.business.entity.vo.LoginUser;
import com.xdjd.mobile.business.util.RedisTool;
import com.xdjd.mobile.business.util.ResponseUtil;
import com.xdjd.mobile.business.util.SpringContextUtils;
import com.xdjd.mobile.system.ApiUtil;
import com.xdjd.mobile.system.anotations.ApiAuth;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ApiAuthInterceptor extends ApiInterceptorAdapter {

    private static final Logger logger = LoggerFactory.getLogger(ApiAuthInterceptor.class);

    private JedisPool jedisPool;

    private Jedis jedis ;

    private String userKey ;
    private String requestKey ;

    private ApiAuth apiAuth ;

    private String apiName ;


    public ApiAuthInterceptor() {
        jedisPool = SpringContextUtils.getBean(JedisPool.class);
        jedis = jedisPool.getResource() ;
    }


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler, Object argu)
            throws Exception {
        boolean validateResult  ;
        validateResult = validateRepeatLock(apiAuth,request,response);
        if ( ! validateResult){
            return validateResult ;
        }
        validateResult = validateLogin(apiAuth,response) ;
        return validateResult ;
    }


    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object serviceObj,
                                Object argu, Object result, Exception e) throws Exception {

        boolean repeatLock = apiAuth.repeatLock();
        if ( ! repeatLock){
            return ;
        }
        try {
            RedisTool.releaseDistributedLock(jedis, userKey, requestKey);
        } finally {
            IOUtils.closeQuietly(jedis);
        }
    }

    private boolean validateLogin(ApiAuth apiAuth,HttpServletResponse response) {
        int loginValidate = apiAuth.loginValidate();
        if (loginValidate == 0){
            return true ;
        }
        if (loginValidate == 1){
            ApiResult result = new ApiResult();
            if (StringUtils.isEmpty(ApiContext.getApiParam().fatchAccessToken())) {
                result.setMsg("未登录");
                result.setCode(-101);
                ResponseUtil.renderJson(response, JSON.toJSONString(result));
                return false;
            }
            LoginUser loginUser = ApiUtil.getCurrentUser();
            if (loginUser == null) {
                result.setMsg("未登录");
                result.setCode(-101);
                ResponseUtil.renderJson(response, JSON.toJSONString(result));
                return false;
            }
        }
        return true ;
    }

    private boolean validateRepeatLock(ApiAuth apiAuth,HttpServletRequest request,HttpServletResponse response) {
        boolean repeatLock = apiAuth.repeatLock();
        if (! repeatLock ){
            return true ;
        }
        userKey = request.getSession().getId();
        requestKey = apiAuth.eventId();
        if (StringUtils.isEmpty(requestKey)){
            requestKey = apiName ;
        }
        if (StringUtils.isEmpty(requestKey)){
            throw new RuntimeException("事件id为空");
        }

        try {
            boolean hasLock = RedisTool.tryGetDistributedLock(jedis, userKey, requestKey, apiAuth.lockTime());
            // 如果没有取到锁，认为是暴击，直接返回
            if (!hasLock) {
                logger.warn("用户（{}）访问{}产生暴击！", request.getRemoteHost(), ApiContext.getApiParam().fatchNameVersion());
                ApiResult result = new ApiResult();
                result.setMsg("您已提交，请耐心等待哦");
                result.setCode(-102);
                ResponseUtil.renderJson(response, JSON.toJSONString(result));
                return false;
            }
        } finally {
            IOUtils.closeQuietly(jedis);
        }
        return true ;
    }

    @Override
    public boolean match(ApiMeta apiMeta) {
        apiName = apiMeta.getName() ;
        apiAuth = apiMeta.getMethod().getAnnotation(ApiAuth.class);
        if (apiAuth == null){
            return false ;

        }
        return true ;
    }




}
